local RoomBase = require 'packages.chess-games.nchess.core.roombase'
local Ch = require "packages.chess-games.nchess"

---@class NChess.Room : NChess.RoomBase, ServerRoomBase
local Room = RoomBase:subclass("NChess.Room")

Room:include(Fk.Base.ServerRoomBase)

local GameLogic = require "packages.chess-games.nchess.server.gamelogic"
local ServerPlayer = require "packages.chess-games.nchess.server.serverplayer"

function Room:initialize(_room)
  RoomBase.initialize(self)
  Fk.Base.ServerRoomBase.initialize(self, _room)

  self.serverplayer_klass = ServerPlayer
  self.logic_klass = GameLogic

  self:addCallback("armistice", self.handleArmistice)
end

function Room:handleArmistice(id, data)
  self:setTag("RequestArmistice", id)
end

function Room:askToArmistice(current)
  if self:getTag("RequestArmistice") then
    local id = self:getTag("RequestArmistice")
    local player = self:getPlayerById(id)
    self:sendLog{
      type = "NChessRequestArmistice",
      arg = player._splayer:getScreenName(),
      arg2 = player.role == "white" and "nchess_white" or "nchess_black",
    }
    local armisticeReq = Request:new(current, "NChess.AskToArmistice")
    armisticeReq:setData(current)
    armisticeReq:setDefaultReply(current, "")
    local result = armisticeReq:getResult(current)
    if result == "ok" then
      self:sendLog{
        type = "NChessAgreeArmistice",
        arg = current._splayer:getScreenName(),
        arg2 = current.role == "white" and "nchess_white" or "nchess_black",
        toast = true
      }
      self:gameOver("white+black")
    else
      self:sendLog{
        type = "NChessRefuseArmistice",
        arg = current._splayer:getScreenName(),
        arg2 = current.role == "white" and "nchess_white" or "nchess_black",
        toast = true
      }
      self:setTag("RequestArmistice", nil)
    end
  end
end

function Room:movePieceTo(pieceId, fromX, fromY, x, y, ignore)
  local rule = RoomBase.movePieceTo(self, pieceId, fromX, fromY, x, y)
  self:doBroadcastNotify("NChess.MovePieceTo", { pieceId, fromX, fromY, x, y }) --这里告诉qml移动
  if Ch:getPieceById(pieceId).name == "pawn" then
    local myColor = pieceId > 0 and "white" or "black"
    if (myColor == "white" and y == 1) or (myColor == "black" and y == 8) then
      local player = self.players[1].role == myColor and self.players[1] or self.players[2]
      self:askToPromote(player, pieceId, x, y)
      rule.type = "promotion"
    end
  end
  if not self:beenMoved(pieceId) then
    local mark = self:getBanner("moved_pieces") or {}
    table.insertIfNeed(mark, pieceId)
    self:setBanner("moved_pieces", mark)
  end
  return rule
end

function Room:syncBoard()
  self:doBroadcastNotify("NChess.SyncBoard", self.board)
end

function Room:canMoveTo(board, fromX, fromY, x, y)
  return RoomBase:canMoveTo(board, fromX, fromY, x, y)
end

function Room:printPiece(name, color, id)
  local piece = RoomBase.printPiece(self, name, color, id)
  self:doBroadcastNotify("NChess.PrintPiece", { name, color, id })
  return piece
end

function Room:addPieceTo(pieceId, x, y)
  RoomBase.addPieceTo(self, pieceId, x, y)
  self:doBroadcastNotify("NChess.AddPieceTo", { pieceId, x, y })
end

function Room:askToPromote(player, pieceId, x, y)
  local name
  local command = "NChess.AskForPromotion"
  local req = Request:new(player, command)
  req:setData(player, { pieceId > 0 and "white" or "black" })
  local result = req:getResult(player)
  if result == "" then
    name = "queen"
  else
    name = result
  end
  self:promote(pieceId, x, y, name)
end

function Room:promote(pieceId, fromX, fromY, name)
  name = name or "queen"
  local myColor = Ch:getPieceById(pieceId):getColor()
  local piece = self:printPiece(name, myColor)
  self:addPieceTo(piece.id, fromX, fromY)
end

return Room

